package xin.alum.aim.coder;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import xin.alum.aim.config.DataAgreement;
import xin.alum.aim.constant.AIMConstant;
import xin.alum.aim.constant.ChannelAttr;
import xin.alum.aim.model.Transportable;
import xin.alum.aim.model.proto.Packet;

import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.util.List;

public class SocksEncoder extends BaseEncoder<Transportable>{

    @Override
    protected void encode(ChannelHandlerContext ctx, Transportable in, List<Object> list) throws Exception {
        Packet.Agreement agreement = ctx.channel().attr(ChannelAttr.AGREEMENT).get();
        if (agreement == null) {
            logger.error("{}未初始化通信协议", ctx.channel());
            return;
        }
        ByteBufAllocator binAlloc = ctx.channel().config().getAllocator();
        boolean isTlv = false;
        ByteBuf binOut;
        byte[] binary;
        switch (agreement) {
            case Json:
            case Text:
                binary = (in.toString() + AIMConstant.TEXT_FRAME_Delimiters).getBytes(StandardCharsets.UTF_8);
                binOut = binAlloc.buffer(binary.length);
                binOut.writeBytes(binary);
                break;
            case Tlv:
                isTlv = true;
            case Binary:
            case ProtoBuf:
                binary = in.getBody();
                if (isTlv) {
                    binOut = binAlloc.buffer(binary.length + 4 + 4);
                    binOut.writeInt(in.getType());
                } else {
                    binOut = binAlloc.buffer(binary.length + 4);
                }
                binOut.writeInt(binary.length);
                binOut.writeBytes(binary);
                break;
            default:
                throw new InvalidParameterException("未知编码协议");
        }
        list.add(binOut);
    }
}
